package idv.cjcat.pyronova.render {
	import flash.geom.Matrix;
	import idv.cjcat.pyronova.errors.RenderVisitorError;
	import idv.cjcat.pyronova.pyro;
	
	public final class RenderVisitor {
		
		private var _width:int;
		private var _height:int;
		
		private var _graphics:Graphics;
		public final function graphics():Graphics { return _graphics; }
		
		public function RenderVisitor(width:int, height:int, graphics:Graphics) {
			_width = width;
			_height = height;
			_graphics = graphics;
		}
		
		
		//matrix
		//------------------------------------------------------------------------------------------------
		
		private var _matrices:Vector.<Matrix> = Vector.<Matrix>([new Matrix()]);
		private var _topMatrixIndex:int = 0;
		private var _firstEmptyIndex:int = 1;
		
		public final function pushMatrix(transform:Matrix):void {
			//expand matrix vector when full
			if (++_topMatrixIndex == _matrices.length) _matrices.length <<= 1;
			if (_topMatrixIndex == _firstEmptyIndex) {
				_matrices[_topMatrixIndex] = new Matrix();
				++_firstEmptyIndex;
			}
			
			var topMatrix:Matrix = _matrices[_topMatrixIndex];
			topMatrix.a = transform.a;
			topMatrix.b = transform.b;
			topMatrix.c = transform.c;
			topMatrix.d = transform.d;
			topMatrix.tx = transform.tx;
			topMatrix.ty = transform.ty;
			topMatrix.concat(_matrices[_topMatrixIndex - 1]);
		}
		
		public final function popMatrix():void {
			if (_topMatrixIndex > 0) --_topMatrixIndex;
			else throw new RenderVisitorError(this, "No more matrix can be popped.");
		}
		
		public final function topMatrix():Matrix {
			return _matrices[_topMatrixIndex];
		}
		
		//------------------------------------------------------------------------------------------------
		//end of matrix
		
		
		//init & finish
		//------------------------------------------------------------------------------------------------
		
		/** @private */
		pyro final function init():void {
			_matrices[0].identity();
			_topMatrixIndex = 0;
		}
		
		/** @private */
		pyro final function finish():void {
			_topMatrixIndex = 0;
		}
		
		//------------------------------------------------------------------------------------------------
		//end of init & finish
	}
}